package base.timer
{
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	
	import utils.HashMap;

	public class TimerFactory
	{
		/**
		 *基础计时器 
		 */		
		private var _timer:Timer;
		/**
		 *计时器任务列表 
		 */		
		private var _hashMap:HashMap;
		/**
		 *当前最大Timer任务ID 
		 */		
		private var _timerMaxID:int=0;
		/**
		 *是否有Timer任务在运行 
		 */		
		private var _running:Boolean=false;
		/**
		 *最后一次时间 
		 */		
		private var _lastTime:int=0;
		
		public function TimerFactory()
		{
			_hashMap=new HashMap();
			_timer=new Timer(20);
			_timer.addEventListener(TimerEvent.TIMER, __onTimer);
		}
		private static var _instance:TimerFactory;
		public static function get Instance() : TimerFactory
		{
			if(_instance == null)
			{
				_instance = new TimerFactory();
			}
			return _instance;
		}
		
		/**
		 * 注册
		 */		
		public function register():void
		{
		}
		
		/**
		 *开始执行 
		 */		
		private function start():void
		{
			if(_hashMap.length>0 && !_timer.running)
			{
				_timer.start();
				_lastTime=getTimer();
				_running=true;
			}
		}
		
		/**
		 *终执全部的执行 
		 */		
		private function stop():void
		{
			_timer.stop();
			_running=false;
		}
		
		private function __onTimer(evt:Event):void
		{
			var time:int=getTimer();
			var dtime:int=time-_lastTime;
			_lastTime=getTimer();
			doTimer(dtime);
		}
		
		private function doTimer(dtime:int):void
		{
			var dic:Dictionary=_hashMap.dictionary;
			for each(var timerTask:TimerTask in dic)
			{
				timerTask.update(dtime);
			}
		}
		
		/**
		 * 指定的延迟时间后，执行Timer任务 
		 * @param delay 延迟时间毫秒
		 * @param callBack 回调函数
		 * @param callBackArgArray 回调函数参数
		 * @return 返回执行Timer任务的唯一ID标识
		 */		
		public function setTimeout(delay:Number, callBack:Function, callBackArgArray:Array=null):int
		{
			return setTimer(delay, callBack, 1, callBackArgArray);
		}
		
		/**
		 * 按照指定的间隔延迟时间，循环执行Timer任务
		 * @param delay 间隔延迟时间
		 * @param callBack 回调函数
		 * @param callBackArgArray 回调函数参数
		 * @return 返回执行Timer任务的唯一ID标识
		 */		
		public function setInterval(delay:Number, callBack:Function, callBackArgArray:Array=null):int
		{
			return setTimer(delay, callBack, 0, callBackArgArray);
		}
		
		/**
		 * 执行Timer
		 * @param delay 计时器事件间的延迟（以毫秒为单位）。 
		 * @param callBack 每次执行完任务后的回调函数
		 * @param repeatCount 设置的计时器运行总次数。 如果重复计数设置为 0，则计时器将持续不断运行，直至调用了 stop() 方法或程序停止。 如果重复计数不为 0，则将运行计时器，运行次数为指定的次数。 如果设置的 repeatCount 总数等于或小于 currentCount，则计时器将停止并且不会再次触发。
		 * @param callBackArgArray 每次执行完任务后的回调函数的参数
		 * @param completeCallBack 任务执行完成后的回调函数
		 * @param completeCallBackArgArray 任务执行完成后的回调函数参数
		 * @return 返回执行Timer任务的唯一ID标识
		 */		
		public function setTimer(delay:Number, callBack:Function, repeatCount:int=0, callBackArgArray:Array=null, completeCallBack:Function=null, completeCallBackArgArray:Array=null):int
		{
			_timerMaxID++;
			var timerTask:TimerTask=new TimerTask(_timerMaxID, delay, callBack, delay, callBackArgArray, completeCallBack, completeCallBackArgArray);
			timerTask.addEventListener(Event.COMPLETE, __onTimerTaskComplete);
			_hashMap.push(_timerMaxID, timerTask);
			start();
			return _timerMaxID;
		}
		
		/**
		 *Timer任务执行完成事件 
		 * @param evt
		 */		
		private function __onTimerTaskComplete(evt:Event):void
		{
			var timerTask:TimerTask=evt.currentTarget as TimerTask;
			removeTimerTask(timerTask);
		}
		
		/**
		 *移除Timer任务 
		 * @param timerTask Timer任务
		 */		
		private function removeTimerTask(timerTask:TimerTask):void
		{
			if(timerTask!=null)
			{
				timerTask.removeEventListener(Event.COMPLETE, __onTimerTaskComplete);
				_hashMap.remove(timerTask.timerID);
				timerTask.dispose();
				timerTask=null;
			}
			if(_hashMap.length<=0)stop();
		}
		
		/**
		 *移除Timer任务 
		 * @param timerID Timer ID
		 */		
		public function removeTimer(timerID:int):void
		{
			var timerTask:TimerTask=_hashMap.remove(timerID) as TimerTask;
			removeTimerTask(timerTask);
		}
	}
}